﻿using System.Threading;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.IO;
using InternetThermostat.DeviceAccessor;
using InternetThermostat.Logging;
using InternetThermostat.Models;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.IO;
using System;
using GHIElectronics.NETMF.Net.NetworkInformation;
using GHIElectronics.NETMF.Net;
using InternetThermostat.Views;
using InternetThermostat.Views.LCD.Fonts;

namespace InternetThermostat
{
    public class Program
    {

        public static void Main()
        {
            Debug.EnableGCMessages(false);



            InitializeNetwork();
            InitializeComponents();
            InitializeWebServer();
            StartScheduleThread();



        }




        private static void StartScheduleThread()
        {
            // This is the start-up temperature
            Schedule.TargetTemperature = 70;
            Schedule.WeeklySchedule = AppSettings.GetDefaultSchedule();

            Thread scheduleThread = new Thread(RunSchedule);
            scheduleThread.Start();
        }

        private static void RunSchedule()
        {
            while (true)
            {
                var curTime = RealTimeClock.GetTime();
                var curDayTime = new DayTime
                {
                    Day = curTime.DayOfWeek,
                    Hour = (byte)curTime.Hour,
                    Minute = (byte)curTime.Minute
                };


                if (Schedule.Override.Contains(curDayTime))
                {
                    Logger.Log("Overriding temperature: " + Schedule.Override[curDayTime]);
                    Schedule.TargetTemperature = (int)Schedule.Override[curDayTime];
                    Schedule.Override.Remove(curDayTime);
                }
                else if (Schedule.WeeklySchedule.Contains(curDayTime))
                {
                    Logger.Log("WeeklySchedule temperature: " + Schedule.WeeklySchedule[curDayTime]);
                    Schedule.TargetTemperature = (int)Schedule.WeeklySchedule[curDayTime];
                }


                Logger.Log("Current Time: " + curDayTime);


                Logger.Log("Current Temperature: " + TemperatureAccessor.GetTemperatureFarenheit());
                Logger.Log("Target Temperature: " + Schedule.TargetTemperature);


                Thread.Sleep(1000 * 60);

            }
        }

        private static void InitializeWebServer()
        {
            WebServices services = new WebServices();
            services.RegisterEndpoints();
            services.StartServer();
        }

        private static void InitializeComponents()
        {
            Debug.EnableGCMessages(false);

            // Mount SD
            FileAccessor.Storage = new PersistentStorage("SD");
            FileAccessor.Storage.MountFileSystem();
            FileAccessor.Root = VolumeInfo.GetVolumes()[0].RootDirectory;


            // Set real time clock to local time
            DeviceAccessor.RealTimeClockAccessor.InitializeClockToLocalTime(AppSettings.NTPServer, AppSettings.NTPOffsetInt);

            Logger.Log("Enable DHCP     " + AppSettings.DHCPEnabled);
            Logger.Log("IP Address:     " + new IPAddress(NetworkInterface.IPAddress).ToString());
            Logger.Log("Subnet Mask:    " + new IPAddress(NetworkInterface.SubnetMask).ToString());
            Logger.Log("Default Getway: " + new IPAddress(NetworkInterface.GatewayAddress).ToString());
            Logger.Log("DNS Server:     " + new IPAddress(NetworkInterface.DnsServer).ToString());

            // Temperature Sensor   
            TemperatureAccessor.ThermometerPin = new AnalogIn(AppSettings.ThermometerPin);
            TemperatureAccessor.ThermometerPin.SetLinearScale(AppSettings.ThermometerMinValue, AppSettings.ThermometerMaxValue);
            Logger.Log("Thermometer: " + AppSettings.ThermometerPin.ToString() + "\t" +
                    AppSettings.ThermometerPin + "\t" + AppSettings.ThermometerPin.GetType());


            // LCD
            FEZ_Components.FEZTouch.LCDConfiguration lcdConfig = new FEZ_Components.FEZTouch.LCDConfiguration(FEZ_Pin.Digital.Di28,
                    FEZ_Pin.Digital.Di20, FEZ_Pin.Digital.Di22, FEZ_Pin.Digital.Di23,
                new FEZ_Pin.Digital[8] { FEZ_Pin.Digital.Di51, FEZ_Pin.Digital.Di50,
                    FEZ_Pin.Digital.Di49, FEZ_Pin.Digital.Di48, FEZ_Pin.Digital.Di47,
                    FEZ_Pin.Digital.Di46, FEZ_Pin.Digital.Di45, FEZ_Pin.Digital.Di44 },
                    FEZ_Pin.Digital.Di24, FEZ_Pin.Digital.Di26, FEZ_Components.FEZTouch.Orientation.Landscape);

            FEZ_Components.FEZTouch.TouchConfiguration touchConfig = new FEZ_Components.FEZTouch.TouchConfiguration(
                SPI.SPI_module.SPI2, FEZ_Pin.Digital.Di25, FEZ_Pin.Digital.Di34);

            AppSettings.Font = new FontCourierNew10();


            View.Lcd = new FEZ_Components.FEZTouch(lcdConfig, touchConfig);
            View.Lcd.ClearScreen();

            HomeView home = new HomeView();


            // Speaker



        }



        private static void InitializeNetwork()
        {
            WIZnet_W5100.Enable(SPI.SPI_module.SPI1, (Cpu.Pin)FEZ_Pin.Digital.Di10, (Cpu.Pin)FEZ_Pin.Digital.Di7, true);

            // initialize tcp stack
            WIZnet_W5100.ReintializeNetworking();

            // set IP address
            if (AppSettings.DHCPEnabled)
            {
                // dynamic IP address
                Dhcp.EnableDhcp(AppSettings.MACAddress, AppSettings.HostName);
            }
            else
            {
                // static IP address
                NetworkInterface.EnableStaticIP(AppSettings.IPAddress, AppSettings.IPMask,
                                                AppSettings.IPGateway, AppSettings.MACAddress);
                NetworkInterface.EnableStaticDns(AppSettings.IPGateway);
            }

        }

    }
}
